package me.zxk.qwert_poetry.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.transaction.Transactional;
import me.zxk.qwert_poetry.dao.*;
import me.zxk.qwert_poetry.dto.request.CollectionCreateDTO;
import me.zxk.qwert_poetry.dto.request.CollectionDeleteDTO;
import me.zxk.qwert_poetry.dto.request.PoemIdCollectionIdDTO;
import me.zxk.qwert_poetry.dto.response.CollectionResponseDTO;
import me.zxk.qwert_poetry.dto.CollectionWithPoemDTO;
import me.zxk.qwert_poetry.dto.response.PoemSimpleResponseDTO;
import me.zxk.qwert_poetry.dto.response.Response;
import me.zxk.qwert_poetry.service.CollectionService;
import me.zxk.qwert_poetry.service.PoemService;
import me.zxk.qwert_poetry.util.ApiException;
import me.zxk.qwert_poetry.util.UserContextHolder;
import me.zxk.qwert_poetry.util.VerifyToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Tag(name = "收藏夹接口")
@RestController
public class CollectionController {
    @Autowired
    private CollectionService collectionService;
    @Autowired
    private PoemService poemService;

    @Operation(summary = "创建收藏夹")
    @VerifyToken
    @PostMapping("/api/collection/create")
    public Response<CollectionResponseDTO> createCollection(@RequestBody CollectionCreateDTO dto) {
        Collection c = new Collection();
        c.setTitle(dto.getTitle());
        c.setDesc(dto.getDesc());
        c.setUser(UserContextHolder.getUserContext().getUser());
        return Response.ok(CollectionResponseDTO.fromEntity(collectionService.createCollection(c)));
    }

    @Operation(summary = "删除收藏夹")
    @PostMapping("/api/collection/delete")
    @VerifyToken
    public Response<Void> deleteCollection(@RequestBody CollectionDeleteDTO collection) {
        collectionService.deleteCollection(collection.getId());
        return Response.ok();
    }

    @Operation(summary = "编辑收藏夹")
    @PostMapping("/api/collection/edit")
    @VerifyToken
    public Response<CollectionResponseDTO> editCollection(@RequestBody Collection collection) {
        User user = UserContextHolder.getUserContext().getUser();
        Collection oldCollection = collectionService.getCollectionById(collection.getId());
        if (oldCollection == null || !oldCollection.getUser().getId().equals(user.getId())) {
            throw new ApiException("收藏夹不存在或不属于当前用户", 1000); // TODO 错误码
        }
        return Response.ok(CollectionResponseDTO.fromEntity(collectionService.editCollection(collection)));
    }

    @Operation(summary = "列出收藏夹")
    @GetMapping("/api/collection/list")
    @VerifyToken
    public Response<List<CollectionResponseDTO>> listCollections() {
        User user = UserContextHolder.getUserContext().getUser();
        var collections = collectionService.listCollectionsByUserId(user.getId());
        return Response.ok(collections.stream().map(CollectionResponseDTO::fromEntity).toList());
    }

    @Operation(summary = "以指定诗词列出收藏夹", description = "列出所有收藏夹，标记指定诗词是否已收藏")
    @GetMapping("/api/collection/list/with_poem")
    @VerifyToken
    public Response<CollectionWithPoemDTO> listCollectionsWithPoem(@RequestParam int poemId) {
        User user = UserContextHolder.getUserContext().getUser();
        Poem poem = poemService.getPoemById(poemId);
        if (poem == null) {
            throw new ApiException("诗词不存在", 1000); // TODO 错误码
        }

        CollectionWithPoemDTO dto = new CollectionWithPoemDTO();
        ArrayList<CollectionWithPoemDTO.CollectionDTO> result = new ArrayList<>();
        for (Collection collection : collectionService.listCollectionsByUserId(user.getId())) {
            var c = new CollectionWithPoemDTO.CollectionDTO();
            c.setCollected(collection.getPoems().contains(poem));
            c.setId(collection.getId());
            c.setName(collection.getTitle());
            result.add(c);
        }

        dto.setCollections(result);
        dto.setPoemId(poemId);
        return Response.ok(dto);
    }

    @Operation(summary = "收藏诗词")
    @PostMapping("/api/collection/poem/collect")
    @VerifyToken
    public Response<Void> collectPoetry(@RequestBody PoemIdCollectionIdDTO dto) {
        User user = UserContextHolder.getUserContext().getUser();
        Collection collection = collectionService.getCollectionById(dto.getCollectionId());
        if (collection == null || !collection.getUser().getId().equals(user.getId())) {
            throw new ApiException("收藏夹不存在或不属于当前用户", 1000); // TODO 错误码
        }
        collectionService.collect(dto.getCollectionId(), dto.getPoemId());
        return Response.ok();
    }

    @Operation(summary = "取消收藏")
    @PostMapping("/api/collection/poem/cancel")
    @VerifyToken
    public Response<Void> cancelCollect(@RequestBody PoemIdCollectionIdDTO dto) {
        User user = UserContextHolder.getUserContext().getUser();
        Collection collection = collectionService.getCollectionById(dto.getCollectionId());
        if (collection == null || !collection.getUser().getId().equals(user.getId())) {
            throw new ApiException("收藏夹不存在或不属于当前用户", 1000); // TODO 错误码
        }
        collectionService.cancel(dto.getCollectionId(), dto.getPoemId());
        return Response.ok();
    }

    @Operation(summary = "批量编辑某诗词", description = "将某诗词批量添加或删除到收藏夹")
    @PostMapping("/api/collection/poem/batch_edit")
    @VerifyToken
    @Transactional
    public Response<Void> batchEditPoem(@RequestBody CollectionWithPoemDTO dto) {
        User user = UserContextHolder.getUserContext().getUser();
        for (var collection : dto.getCollections()) {
            Collection collectionInDb = collectionService.getCollectionById(collection.getId());
            if (collectionInDb == null || !collectionInDb.getUser().getId().equals(user.getId())) {
                throw new ApiException("收藏夹不存在或不属于当前用户", 1000); // TODO 错误码
            }
            if (collection.getCollected())
                collectionService.collect(collection.getId(), dto.getPoemId());
            else
                collectionService.cancel(collection.getId(), dto.getPoemId());
        }
        return Response.ok();
    }

    @Operation(summary = "列出收藏夹所有诗词")
    @GetMapping("/api/collection/poem/list")
    @VerifyToken
    public Response<List<PoemSimpleResponseDTO>> listPoemsInCollection(@RequestParam int collectionId) {
        User user = UserContextHolder.getUserContext().getUser();
        Collection collection = collectionService.getCollectionById(collectionId);
        if (collection == null || !collection.getUser().getId().equals(user.getId())) {
            throw new ApiException("收藏夹不存在或不属于当前用户", 1000); // TODO 错误码
        }
        return Response.ok(collection.getPoems().stream().map(p -> PoemSimpleResponseDTO.fromEntity(p, poemService)).toList());
    }
}
